package com.theaf.basemodule.service.impl.core;

import com.alibaba.dubbo.config.annotation.Service;
import com.theaf.basemodule.common.api.DataRange;
import com.theaf.basemodule.dao.*;
import com.theaf.basemodule.dao.OrganDAO;
import com.theaf.basemodule.dao.PositionDAO;
import com.theaf.basemodule.dao.ResourceDAO;
import com.theaf.basemodule.dao.UserDAO;
import com.theaf.basemodule.service.impl.UserServiceImpl;
import com.theaf.core.api.UserComService;
import com.theaf.core.api.model.Menu;
import com.theaf.core.api.model.UserInfo;
import com.theaf.core.cache.RedisHelper;
import com.theaf.core.repo.specification.SqlBuilder;
import com.theaf.basemodule.common.model.SysResource;
import com.theaf.basemodule.common.model.SysUser;
import com.theaf.basemodule.common.model.SysUserRange;
import com.theaf.core.utils.DictionaryHelper;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 宋文科
 * @create 2017-12-26 11:09
 **/
@Service
public class UserServiceDubboImpl implements UserComService{

    @Resource
    private UserDAO userDAO;

    @Resource
    private OrganDAO organDAO;

    @Resource
    private ResourceDAO resourceDAO;

    @Resource
    private PositionDAO positionDAO;

    @Autowired
    private Mapper mapper;

    @Override
    public List<Menu> findMenuByUserId(Long aLong, String s) {
        return null;
    }

    /**
     * 根据用户查询权限
     * @param userId
     * @return
     */
    @Override
    public List<Menu> findAuthByUserId(Long userId) {
        List<Menu> auths =  (ArrayList<Menu>)RedisHelper.get(UserServiceImpl.REDIS_AUTHS+userId);
        if(auths==null) {
            auths = new ArrayList();
            /*for(SysResource n:resourceDAO.findUserFun(userId)){
                Menu menu = BeanMapper.map(n,Menu.class);
                menu.setUrl(n.getUrl());
                auths.add(menu);
            }*/
            if(auths.size()>0) {
                RedisHelper.set(UserServiceImpl.REDIS_AUTHS + userId, auths, 5 * 60 * 1000);
            }
        }
        return auths;
    }

    @Override
    public List<String> getAllFunUrl() {
        List<SysResource> resources = (List<SysResource>)RedisHelper.get(UserServiceImpl.REDIS_MENU);
        return resources.parallelStream().map(n->n.getUrl()).collect(Collectors.toList());
    }

    /**
     * 查询机构范围
     * @param userId
     * @return
     */
    @Override
    public List<Long> findOrganRangeByUserId(Long userId) {
        List<Long> ids = (List<Long>)RedisHelper.get(UserServiceImpl.REDIS_DATA_RANGE+userId);
        if(ids!=null){
            return ids;
        }else {
            SysUser user = userDAO.findOne(userId);
            if (user != null) {
                    for (SysUserRange v : user.getSysUserRanges()) {
                        if (v.getType().intValue()==SysUserRange.TYPE_ORG) {//机构选择
                            if (v.getRangType().intValue()==1) {
                                if(v.isExcluded()){
                                    ids.remove(new Long(v.getObjId()));
                                }else{
                                    ids.add(new Long(v.getObjId()));
                                }
                            } else if (v.getRangType().intValue()==2) {
                                if(v.isExcluded()){
                                    ids.remove(new Long(v.getObjId()));
                                    organDAO.findChildId(new Long(v.getObjId())).forEach(n->ids.remove(n));
                                }else {
                                    ids.add(new Long(v.getObjId()));
                                    ids.addAll(organDAO.findChildId(new Long(v.getObjId())));
                                }
                            } else {
                                if(v.isExcluded()) {
                                    ids.add(new Long(v.getObjId()));
                                    ids.addAll(organDAO.findChildAllId(new Long(v.getObjId())));
                                }else{
                                    ids.add(new Long(v.getObjId()));
                                    ids.addAll(organDAO.findChildAllId(new Long(v.getObjId())));
                                }
                            }
                        } else {//自定义范围
                            String classPath = DictionaryHelper.getChlidMemo(
                                    UserServiceImpl.DIC_CUSOT_DATA_RANGE, v.getObjId());
                            try {
                                DataRange dataRange = (DataRange) Class.forName(classPath).newInstance();
                                ids.addAll(dataRange.findRange(userId));
                            } catch (Exception e) {
                                //e.printStackTrace();
                            }
                        }
                    }
            }
            RedisHelper.set(UserServiceImpl.REDIS_DATA_RANGE+userId,ids,24*60*60*1000);
            return ids;
        }
    }

    private UserInfo toUserInfo(SysUser sysUser){
        UserInfo userInfo = mapper.map(sysUser,UserInfo.class);
        //userInfo.setBusPlate(new LinkedHashMap());
       // String[] plates = sysUser.getBusPlate().split(",");
//        for(String plate:plates){
//            String[] ps = plate.split("\\:");
//            userInfo.getBusPlate().put(ps[0],ps[1]);
//        }
        return userInfo;
    }

    private List<UserInfo> toUserInfos(List<SysUser> users){
        return users.parallelStream().map(n->toUserInfo(n)).collect(Collectors.toList());
    }

    @Override
    public List<UserInfo> findCustion(Map<String, Object> term, Map<String, Boolean> order) {
        List<SysUser> users = userDAO.findCustom(term,order);
        return toUserInfos(users);
    }

    @Override
    public List<UserInfo> query(Specification specification) {
        List<SysUser> users = userDAO.query(specification);
        return toUserInfos(users);
    }

    @Override
    public List<UserInfo> findByOrgan(Long orgId) {
        List<SysUser> users = userDAO.findAll(SqlBuilder.start("orgId",orgId).gen());
        return toUserInfos(users);
    }

    @Override
    public List<UserInfo> findByOrganAndPosition(Long orgId, Long posId) {
        List<SysUser> users = userDAO.findAll(SqlBuilder.start("orgId",orgId).
                and("position.id",posId).gen());
        return toUserInfos(users);
    }
}